﻿/*  
	------------------------------------------------------------------------
	 NQ Core Library
	
	 Homepage: http://www.awzhome.de/
	------------------------------------------------------------------------
	
	This Source Code Form is subject to the terms of the Mozilla Public
	License, v. 2.0. If a copy of the MPL was not distributed with this
	file, You can obtain one at http://mozilla.org/MPL/2.0/.
   
	The Original Code is code of NQ Core Library.

	The Initial Developer of the Original Code is Andreas Weizel.
	Portions created by the Initial Developer are
	Copyright (C) 2012 Andreas Weizel. All Rights Reserved.
	
	Contributor(s): (none)
	
	------------------------------------------------------------------------
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AWZhome.NQ.Core
{
	/// <summary>
	/// Class containing some extension methods for easier usage of
	/// <see cref="AWZhome.NQ.Core.INQServiceManager">INQServiceManager</see>
	/// interface.
	/// </summary>
	public static class NQServiceManagerExtensions
	{
		/// <summary>
		/// Retrieves an instance of a single-instance service object.
		/// </summary>
		/// <typeparam name="T">Type of the returned service instance.</typeparam>
		/// <returns>Instance of the service object, typed as set by the <typeparamref name="T">T</typeparamref> parameter.</returns>
		/// <remarks>
		/// <para>This method retrieves instances of single-instance services only. Please use
		/// <see cref="AWZhome.NQ.Core.INQServiceManager.CreateService">CreateService</see> for multi-instance services.
		/// </para>
		/// <para>
		/// <c>GetService</c> resolves any service substitutes (see also
		/// <see cref="AWZhome.NQ.Core.NQServiceSubstituteAttribute">NQServiceSubstituteAttribute</see>). So if the requested
		/// service has been substituted by another service, this method will return an instance of that substituting service.
		/// </para>
		/// <para>
		/// GetService can't be called until all single-instance services are initialized. A service
		/// might suspend this lock during its own initialization by calling
		/// <see cref="AWZhome.NQ.Core.INQServiceManager.SuspendServiceInitLock">SuspendServiceInitLock</see> method.
		/// </para>
		/// </remarks>
		public static T GetService<T>(this INQServiceManager serviceManager)
		{
			return serviceManager.GetService<T>(typeof(T));
		}

		/// <summary>
		/// Retrieves an instance of a multi-instance service object.
		/// </summary>
		/// <typeparam name="T">Type of the retrieved service instance.</typeparam>
		/// <returns>Instance of the service object, typed as set by the <typeparamref name="T">T</typeparamref> parameter.</returns>
		/// <remarks>
		/// <para>This method creates instances of multi-instance services only. Please use
		/// <see cref="AWZhome.NQ.Core.INQServiceManager.GetService">GetService</see> for single-instance services.
		/// </para>
		/// <para>
		/// <c>CreateService</c> resolves any service substitutes. So if the requested
		/// service has been substituted by another service, this method will return an instance of that substituting service.
		/// </para>
		/// </remarks>
		public static T CreateService<T>(this INQServiceManager serviceManager)
		{
			return serviceManager.CreateService<T>(typeof(T));
		}

		/// <summary>
		/// Directly retrieves an instance of a multi-instance service object.
		/// </summary>
		/// <typeparam name="T">Type of the returned service instance.</typeparam>
		/// <returns>Instance of the service object.</returns>
		/// <remarks>
		/// <para>This method creates instances of multi-instance services only.
		/// </para>
		/// <para>
		/// <c>CreateServiceDirect</c> ignores any service substitutes, what means that the resulting object instance always will
		/// be of the requested service.
		/// </para>
		/// </remarks>
		public static T CreateServiceDirect<T>(this INQServiceManager serviceManager)
		{
			return serviceManager.CreateServiceDirect<T>(typeof(T));
		}

		/// <summary>
		/// Retrieves an instance of a multi-instance dependent service object and passes its
		/// parent service through its constructor.
		/// </summary>
		/// <typeparam name="T">Type of the returned service instance.</typeparam>
		/// <typeparam name="S">Type of parent service given by <paramref cref="dependent">dependent</paramref>.</typeparam>
		/// <param name="dependent">Instance of the parent service the created service depends on.</param>
		/// <returns>Instance of the service object, typed as set by the <typeparamref name="T">T</typeparamref> parameter.</returns>
		/// <remarks>
		/// <para>This method creates instances of multi-instance services only. Please use
		/// <see cref="AWZhome.NQ.Core.INQServiceManager.GetService">GetService</see> for single-instance services.
		/// </para>
		/// <para>
		/// <c>CreateService</c> resolves any service substitutes. So if the requested
		/// service has been substituted by another service, this method will return an instance of that substituting service.
		/// </para>
		/// </remarks>
		public static T CreateDependentService<T, S>(this INQServiceManager serviceManager, S dependent)
		{
			return serviceManager.CreateDependentService<T, S>(typeof(T), dependent);
		}

		/// <summary>
		/// Retrieves an instance of a multi-instance dependent service object and passes its two
		/// parent services through its constructor.
		/// </summary>
		/// <param name="dep1">Instance of the first parent service the created service depends on.</param>
		/// <param name="dep2">Instance of the second parent service the created service depends on.</param>
		/// <typeparam name="T">Type of the returned service instance.</typeparam>
		/// <typeparam name="S1">Type of the first parent service given by <paramref cref="dep1">dep1</paramref>.</typeparam>
		/// <typeparam name="S2">Type of the second parent service given by <paramref cref="dep2">dep2</paramref>.</typeparam>
		/// <returns>Instance of the service object.</returns>
		/// <remarks>
		/// <para>This method creates instances of multi-instance services only. Please use
		/// <see cref="AWZhome.NQ.Core.INQServiceManager.GetService">GetService</see> for single-instance services.
		/// </para>
		/// <para>
		/// <c>CreateService</c> resolves any service substitutes (see also
		/// <see cref="AWZhome.NQ.Core.NQServiceSubstituteAttribute">NQServiceSubstituteAttribute</see>). So if the requested
		/// service has been substituted by another service, this method will return an instance of that substituting service.
		/// </para>
		/// </remarks>
		public static T CreateDependentService2<T, S1, S2>(this INQServiceManager serviceManager, S1 dep1, S2 dep2)
		{
			return serviceManager.CreateDependentService2<T, S1, S2>(typeof(T), dep1, dep2);
		}

		/// <summary>
		/// Checks if a certain single-instance service is running.
		/// </summary>
		/// <typeparam name="T">Registered service interface.</typeparam>
		/// <returns><c>true</c>, if the service is existing, <c>false</c> otherwise.</returns>
		public static bool IsServiceRunning<T>(this INQServiceManager serviceManager)
		{
			return serviceManager.IsServiceRunning(typeof(T));
		}

		/// <summary>
		/// Checks if a certain multi-instance service is registered and an instance can be created.
		/// </summary>
		/// <typeparam name="T">Registered service interface.</typeparam>
		/// <returns><c>true</c>, if an instance of the service can be created, <c>false</c> otherwise.</returns>
		public static bool IsServiceCreatable<T>(this INQServiceManager serviceManager)
		{
			return serviceManager.IsServiceCreatable(typeof(T));
		}
	}
}
